package com.jingyanzi.privilege.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jingyanzi.privilege.dao.SecurityMenuMapper;
import com.jingyanzi.privilege.dao.SecurityRolebtnMapper;
import com.jingyanzi.privilege.dao.SecurityRolemenuMapper;
import com.jingyanzi.privilege.domain.BtnDO;
import com.jingyanzi.privilege.domain.MenuDO;
import com.jingyanzi.privilege.domain.result.ResultDO;
import com.jingyanzi.privilege.domain.result.ResultSupport;
import com.jingyanzi.privilege.entity.SecurityMenu;
import com.jingyanzi.privilege.entity.SecurityMenuExample;
import com.jingyanzi.privilege.entity.SecurityMenuExample.Criteria;
import com.jingyanzi.privilege.entity.SecurityRolebtn;
import com.jingyanzi.privilege.entity.SecurityRolebtnExample;
import com.jingyanzi.privilege.entity.SecurityRolemenu;
import com.jingyanzi.privilege.entity.SecurityRolemenuExample;

import com.jingyanzi.privilege.query.BtnQueryDO;
import com.jingyanzi.privilege.query.MenuQueryDO;
import com.jingyanzi.privilege.service.IBtnService;
import com.jingyanzi.privilege.service.IMenuService;
import com.jingyanzi.privilege.util.BeanUtilsExtends;


@Service("menuService")
public class MenuServiceImpl extends BaseServiceImpl implements IMenuService {

	@Autowired
	private SecurityMenuMapper menuMapper;

	@Autowired
	private SecurityRolemenuMapper roleMenuMapper;

	@Autowired
	private SecurityRolebtnMapper roleBtnMapper;

	@Autowired
	private IBtnService btnService;

	public ResultDO getMenuParent(Integer menuId) {

		ResultSupport result = new ResultSupport();

		List<Integer> pMenuIds = new ArrayList<Integer>();
		SecurityMenu menu = new SecurityMenu();

		menu.setMenuId(menuId);

		do {
			try {
				menu = menuMapper.selectByPrimaryKey(menu.getMenuId());
			} catch (Exception e) {
				e.printStackTrace();
				//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("获取菜单信息失败");
				result.setSuccess(false);
				return result;
			}
			if (menu == null) {
				//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("获取菜单信息失败");
				result.setSuccess(false);
				return result;
			}

			pMenuIds.add(menu.getId());
		} while (menu.getMenuId() != null && menu.getMenuId() != 0);

		result.setModel(ResultSupport.FIRST_MODEL_KEY, pMenuIds);

		return result;

	}

	public ResultDO add(MenuDO menuDO) {

		SecurityMenu menu = new SecurityMenu();

		ResultSupport result = BeanUtilsExtends.copy(menu, menuDO);

		if (!result.isSuccess()) {
			//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("对象转换失败");
			result.setSuccess(false);
			return result;
		}
		// menu.setCode(UUID.randomUUID().toString());
		menu.setCreatetime(Calendar.getInstance().getTime());
		menu.setStatus(1);
		menu.setIsDelete(1);

		SecurityMenu pMenu = null;
		// 为0建立根节点
		if (menu.getMenuId() != 0) {
			try {
				pMenu = menuMapper.selectByPrimaryKey(menu.getMenuId());
			} catch (Exception e) {
				e.printStackTrace();
				//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("获取菜单信息失败");
				result.setSuccess(false);
				return result;
			}
			if (pMenu != null) {
				// 为新增加的菜单添加父菜单
				menu.setpCode(pMenu.getCode());
			} else {
				//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("获取菜单信息失败");
				result.setSuccess(false);
				return result;
			}
		}

		int r = -1;
		try {
			r = menuMapper.insert(menu);
		} catch (Exception e) {
			e.printStackTrace();
			//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("添加菜单信息失败");
			result.setSuccess(false);
			return result;
		}
		if (r < 1) {
			//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("添加菜单信息失败");
			result.setSuccess(false);
			return result;
		}
		result.setModel(ResultDO.FIRST_MODEL_KEY, menu.getId());
		return result;
	}

	public ResultDO remove(Integer id) {

		ResultSupport result = new ResultSupport();

		SecurityMenu menu = new SecurityMenu();

		try {
			menu = menuMapper.selectByPrimaryKey(id);
		} catch (Exception e) {
			e.printStackTrace();
			//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("获取菜单信息失败");
			result.setSuccess(false);
			return result;
		}

		if (!isDelete(id)) {
			//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("判断第三级菜单是否删除失败");
			result.setSuccess(false);
			return result;
		}

		menu.setId(id);
		menu.setIsDelete(-1);

		int r = -1;

		r = removeMapping(id);

		BtnQueryDO query = new BtnQueryDO();
		query.setMenuId(id);
		// 删除菜单下面所有的按钮
		ResultDO res = btnService.removeForMenuId(query);

		if (!res.isSuccess()) {
			result.setErrorCode(ResultDO.MENU_DELETE_ERROR);
			result.setErrorMsg("删除菜单下所有按钮失败");
			result.setSuccess(false);
			return result;
		}

		if (r > -1) {
			try {
				r = -1;
				r = menuMapper.updateByPrimaryKeySelective(menu);
			} catch (Exception e) {
				//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("删除菜单失败");
				result.setSuccess(false);
				return result;
			}
		}
		if (r < 1) {
			//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("删除菜单失败");
			result.setSuccess(false);
			return result;
		}

		return result;
	}

	private boolean isDelete(Integer id) {

		SecurityMenuExample example = new SecurityMenuExample();

		example.createCriteria().andIsDeleteEqualTo(1).andTopEqualTo(2).andMenuIdEqualTo(id);

		int count = 0;

		try {
			count = menuMapper.countByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (count == 0)
			return true;
		return false;
	}

	public ResultDO modifi(MenuDO menuDO) {

		SecurityMenu menu = new SecurityMenu();

		ResultSupport result = BeanUtilsExtends.copy(menu, menuDO);
		if (!result.isSuccess()) {
			//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("对象转换失败");
			result.setSuccess(false);
			return result;
		}
		menu.setCreatetime(Calendar.getInstance().getTime());

		int r = -1;
		try {
			r = menuMapper.updateByPrimaryKeySelective(menu);
		} catch (Exception e) {
			e.printStackTrace();
			//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("修改菜单失败");
			result.setSuccess(false);
			return result;
		}
		if (r < 1) {
			//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("修改菜单失败");
			result.setSuccess(false);
			return result;
		}

		return result;
	}

	public ResultDO get(Integer id) {

		ResultSupport result = new ResultSupport();

		if (id < 1) {
			result.setSuccess(false);
			return result;
		}

		SecurityMenu menu = null;

		try {
			menu = menuMapper.selectByPrimaryKey(id);
		} catch (Exception e) {
			e.printStackTrace();
			//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("获取菜单信息失败");
			result.setSuccess(false);
			return result;
		}

		if (menu == null) {
			//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("获取菜单信息失败");
			result.setSuccess(false);
			return result;
		}

		/*BtnQueryDO query1 = new BtnQueryDO();
		query1.setMenuId(id);*/

		//ResultDO res = btnService.query(query1);

		/*if (!res.isSuccess()) {
			result.setErrorCode(ResultDO.MENU_GET_ERROR);
			result.setErrorMsg("获取按钮信息失败");
			result.setSuccess(false);
			return result;
		}*/

		MenuDO menuDO = getMenuDO(menu);
		// 得到菜单下面的按钮
		//menuDO.setBtns((List<BtnDO>) res.getModel(ResultSupport.FIRST_MODEL_KEY));

		MenuQueryDO query2 = new MenuQueryDO();
		query2.setMenuId(id);
		query2.setTop0(0);
		query2.setTop1(0);
		query2.setTop2(0);
		// 得到子菜单
		ResultDO res = this.query(query2);

		if (!res.isSuccess()) {
			result.setErrorCode(ResultDO.MENU_DELETE_ERROR);
			result.setErrorMsg("获取子菜单失败");
			result.setSuccess(false);
			return result;
		}

		menuDO.setChildren((List<MenuDO>) res.getModel(ResultSupport.FIRST_MODEL_KEY));

		result.setModel(ResultSupport.FIRST_MODEL_KEY, menuDO);
		return result;
	}

	public ResultDO getMenuList(Integer id) {

		ResultSupport result = new ResultSupport();

		SecurityMenuExample example = new SecurityMenuExample();

		List<MenuDO> allMenuList = new ArrayList<MenuDO>();

		List<SecurityMenu> list = null;

		if (id == 0) {
			example.setOrderByClause("sortNum asc");
			example.createCriteria().andIsDeleteEqualTo(1).andTopEqualTo(0);
		} else {
			example.createCriteria().andMenuIdEqualTo(id).andIsDeleteEqualTo(1).andTopEqualTo(0);
		}

		try {
			list = menuMapper.selectByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
			//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("获取菜单失败");
			result.setSuccess(false);
			return result;
		}

		for (MenuDO menuDO : getMenuDOList(list)) {
			SecurityMenuExample example1 = new SecurityMenuExample();
			example1.setOrderByClause("sortNum asc");
			example1.createCriteria().andIsDeleteEqualTo(1).andTopEqualTo(1).andMenuIdEqualTo(menuDO.getId());
			List<MenuDO> allSubMenuList = new ArrayList<MenuDO>();
			List<SecurityMenu> list1 = null;
			try {
				list1 = menuMapper.selectByExample(example1);
			} catch (Exception e) {
				e.printStackTrace();
				//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("获取菜单失败");
				result.setSuccess(false);
				return result;
			}

			for (MenuDO subMenuDO : getMenuDOList(list1)) {
				SecurityMenuExample example2 = new SecurityMenuExample();
				example2.setOrderByClause("sortNum asc");
				example2.createCriteria().andIsDeleteEqualTo(1).andTopEqualTo(2).andMenuIdEqualTo(subMenuDO.getId());
				List<SecurityMenu> list2 = null;
				try {
					list2 = menuMapper.selectByExample(example2);
				} catch (Exception e) {
					e.printStackTrace();
					//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
					result.setErrorMsg("获取菜单失败");
					result.setSuccess(false);
					return result;
				}
				
				List<MenuDO> mListDO = getMenuDOList(list2);
				for(MenuDO menu : mListDO) {
					BtnQueryDO query = new BtnQueryDO();
					query.setMenuId(menu.getId());
					System.out.println("查询菜单ID：" + menu.getId() + "对应的btn");
					ResultDO res = btnService.query(query);
					if(!res.isSuccess()) {
						result.setErrorMsg("获取菜单对应的按钮失败");
						result.setSuccess(false);
						return result;
					}
					
					List<BtnDO> btnListDO = (List<BtnDO>) res.getModel(ResultSupport.FIRST_MODEL_KEY);
					menu.setBtns(btnListDO);
				}
				subMenuDO.setChildren(mListDO);
				
				BtnQueryDO query = new BtnQueryDO();
				query.setMenuId(subMenuDO.getId());
				System.out.println("查询菜单ID：" + subMenuDO.getId() + "对应的btn");
				ResultDO res = btnService.query(query);
				if(!res.isSuccess()) {
					result.setErrorMsg("获取菜单对应的按钮失败");
					result.setSuccess(false);
					return result;
				}
				
				List<BtnDO> btnListDO = (List<BtnDO>) res.getModel(ResultSupport.FIRST_MODEL_KEY);
				System.out.println(btnListDO);
				subMenuDO.setBtns(btnListDO);
				
				allSubMenuList.add(subMenuDO);
			}
			menuDO.setChildren(allSubMenuList);
			allMenuList.add(menuDO);
		}

		result.setModel(ResultSupport.FIRST_MODEL_KEY, allMenuList);
		return result;

	}

	public ResultDO query(MenuQueryDO query) {

		ResultSupport result = new ResultSupport();

		List<SecurityMenu> list = null;

		SecurityMenuExample example = new SecurityMenuExample();
		Criteria createCriteria = example.createCriteria();
		if (StringUtils.isNotBlank(query.getNamecode())) {
			createCriteria.andNameLike("%" + query.getNamecode() + "%");
		}

		if (query.getMenuId() != 0) {
			createCriteria.andMenuIdEqualTo(query.getMenuId());
		}

		if (query.getTop0() == 1) {
			createCriteria.andTopEqualTo(0);
		}

		if (query.getTop1() == 1) {
			createCriteria.andTopEqualTo(1);
		}

		if (query.getTop2() == 1) {
			createCriteria.andTopEqualTo(2);
		}

		createCriteria.andIsDeleteEqualTo(1).andTopEqualTo(0);

		List<MenuDO> menuDOList = null;

		if (query.isPage()) {
			example.setLimitByPage(query.getStart() + "," + query.getPageRows());
			long count = menuMapper.countByExample(example);
			result.setModel(ResultSupport.SECOND_MODEL_KEY, count);
		}

		example.setOrderByClause("sortNum asc");
		
		try {
			list = menuMapper.selectByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
			//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("获取菜单失败");
			result.setSuccess(false);
			return result;
		}

		menuDOList = getMenuDOList(list);

		result.setModel(ResultSupport.FIRST_MODEL_KEY, menuDOList);

		return result;
	}

	public ResultDO queryForRoleId(Integer roleId) {

		ResultSupport result = new ResultSupport();

		SecurityRolemenuExample example1 = new SecurityRolemenuExample();

		example1.createCriteria().andRoleidEqualTo(roleId);

		List<SecurityRolemenu> list = roleMenuMapper.selectByExample(example1);

		List<MenuDO> menuDOList = new ArrayList<MenuDO>();

		for (SecurityRolemenu v : list) {
			try {
				// 得到主菜
				SecurityMenuExample example2 = new SecurityMenuExample();
				example2.createCriteria().andIdEqualTo(v.getId()).andMenuIdIsNull();
				List<SecurityMenu> list2 = menuMapper.selectByExample(example2);
				MenuDO menuDO = getMenuDO(list2.get(0));
				// 根据主菜单得到子菜单
				example2.createCriteria().andMenuIdEqualTo(v.getId());
				List<SecurityMenu> list3 = menuMapper.selectByExample(example2);
				menuDO.setChildren(getMenuDOList(list3));

				menuDOList.add(menuDO);
			} catch (Exception e) {
				//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("获取菜单失败");
				result.setSuccess(false);
				return result;
			}
		}

		result.setModel(ResultSupport.FIRST_MODEL_KEY, menuDOList);

		return result;

	}

	public ResultDO getSubMenu(Integer id) {

		ResultSupport result = new ResultSupport();

		if (id == null) {
			result.setErrorCode(ResultDO.MENU_DELETE_ERROR);
			result.setErrorMsg("查找主菜单失败");
			result.setSuccess(false);
			return result;
		}

		SecurityMenuExample example = new SecurityMenuExample();

		example.createCriteria().andMenuIdEqualTo(id).andIsDeleteEqualTo(1);

		List<SecurityMenu> list = null;

		try {
			list = menuMapper.selectByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
			//result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("获取菜单信息失败");
			result.setSuccess(false);
			return result;
		}

		if (list == null) {
			result.setErrorCode(ResultDO.MENU_QUERY_ERROR);
			result.setErrorMsg("没有关联的菜单信息");
			result.setSuccess(false);
			return result;
		}

		result.setModel(ResultSupport.FIRST_MODEL_KEY, getMenuDOList(list));
		return result;
	}

	public ResultDO queryRoleMenu(MenuQueryDO query) {

		ResultSupport result = new ResultSupport();

		ResultDO resultDO = getMenuList(0);

		List<MenuDO> mainList = (List<MenuDO>) resultDO.getModel(ResultSupport.FIRST_MODEL_KEY);

		List<MenuDO> menuList = new ArrayList<MenuDO>();

		for (MenuDO menuDO : mainList) {

			List<MenuDO> subMenuDOList = new ArrayList<MenuDO>();
			for (MenuDO subMenuDO : menuDO.getChildren()) {
				
				List<MenuDO> topMenuDOList = new ArrayList<MenuDO>();
				for (MenuDO topMenuDO : subMenuDO.getChildren()) {
					List<BtnDO> btnDOList = isChcekMenuIsBtns(topMenuDO, query.getRoleId());
					if (btnDOList.size() != 0) {
						topMenuDO.setBtns(btnDOList);
					}
					topMenuDOList.add(isCheckMenu(topMenuDO, query.getRoleId()));
				}
				List<BtnDO> btnDOList = isChcekMenuIsBtns(subMenuDO, query.getRoleId());
				if (btnDOList.size() != 0) {
					subMenuDO.setBtns(btnDOList);
				}
				if (topMenuDOList.size() != 0) {
					subMenuDO.setChildren(topMenuDOList);
				}
				subMenuDOList.add(isCheckMenu(subMenuDO, query.getRoleId()));
			}
			List<BtnDO> btnDOList = isChcekMenuIsBtns(menuDO, query.getRoleId());
			if (btnDOList.size() != 0) {
				menuDO.setBtns(btnDOList);
			}
			if (subMenuDOList.size() != 0) {
				menuDO.setChildren(subMenuDOList);
			}
			menuList.add(isCheckMenu(menuDO, query.getRoleId()));
		}

		result.setModel(ResultSupport.FIRST_MODEL_KEY, menuList);

		return result;
	}

	private MenuDO isCheckMenu(MenuDO menuDO, int roleId) {

		List<SecurityRolemenu> list = null;

		SecurityRolemenuExample example = new SecurityRolemenuExample();

		example.createCriteria().andRoleidEqualTo(roleId);

		try {
			list = roleMenuMapper.selectByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (list != null) {
			for (SecurityRolemenu roleMenu : list) {
				if (menuDO.getId().intValue() == roleMenu.getMenuid().intValue()) {
					menuDO.setForIsCheck(1);
				}
			}
		}
		return menuDO;
	}

	private List<BtnDO> isChcekMenuIsBtns(MenuDO menuDO, int roleId) {

		SecurityRolebtnExample example = new SecurityRolebtnExample();
		List<SecurityRolebtn> list = null;
		
		example.createCriteria().andRoleidEqualTo(roleId);
		try {
			list = roleBtnMapper.selectByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
		}

		BtnQueryDO q = new BtnQueryDO();
		q.setMenuId(menuDO.getId());
		ResultDO resultDO = btnService.query(q);
		List<BtnDO> btnList = (List<BtnDO>) resultDO.getModel(ResultSupport.FIRST_MODEL_KEY);

		for (BtnDO btn : btnList) {
			btn.setIsCheck(0);
			if (list != null) {
				for (SecurityRolebtn roleBtn : list) {
					if (btn.getId().intValue() == roleBtn.getBtnid().intValue()) {
						btn.setIsCheck(1);
					}
				}
			}
		}

		return btnList;
	}

	private int removeMapping(int id) {

		int r = -1;

		SecurityRolemenuExample example2 = new SecurityRolemenuExample();

		example2.createCriteria().andMenuidEqualTo(id);
		try {
			r = roleMenuMapper.deleteByExample(example2);
		} catch (Exception e) {
			return -1;
		}

		if (r < -1) {
			return -1;
		}

		return 1;
	}

}
